/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pl.makimo.fuzzy.sets;

import java.util.HashMap;

import pl.makimo.fuzzy.sets.memberships.DiscreteMembershipFunction;
import pl.makimo.fuzzy.sets.memberships.MembershipFunction;

/**
 *
 * @author Mateusz Papiernik
 */
public class Type2DiscreteFuzzySet<T> extends Type2FuzzySet<T> {
	public CrispSet<T> elements = new CrispSet<T>();
	
    public Type2DiscreteFuzzySet(MembershipFunction membershipFunction) {
		super();
		this.membershipFunction = membershipFunction;
	}
	
    @Override
    public FuzzySet<T> support() {    	    	
    	HashMap<Object, Object> memberships = new HashMap<Object, Object>();
    	
    	for (T element : elements) {     		
    		Object value = this.value(element);

    		if (value instanceof FuzzySet) {
   				memberships.put(this.realValue(element), ((FuzzySet)value).maxMembership());
    		} else {    			
    			memberships.put(this.realValue(element), (double)0.0);
    		}
    	}
    	
    	DiscreteFuzzySet<T> set = new DiscreteFuzzySet<T>(new DiscreteMembershipFunction(memberships));
    	set.elements = this.elements;
    	set.column = this.column;
    	
    	return set;
    }
    
    @Override
    public double in() {
    	return (double)support().cardinality() / crispCardinality();
    }
    
    @Override
    public double crispCardinality() {
    	return (double)elements.cardinality();
    }
    
    @Override
    public double cardinality() {
    	return nfsigmaCount();
    }

    public double nfsigmaCount() {
    	double card = 0.0;
    	
    	for (T element : elements) {
    		FuzzySet set = (FuzzySet)this.value(element);
    		card += set.maxWithOne();
    	}
    	
    	return card;    	
    }

	@Override
	public double maxWithOne() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public double maxMembership() {
		// TODO Auto-generated method stub
		return 0;
	}
	
	public static <T> Type2DiscreteFuzzySet<T> fromType1(final DiscreteFuzzySet<T> set) {
		HashMap<Object, Object> mappings = new HashMap<Object, Object>();
		
		for (final T element : set.elements) {
			DiscreteFuzzySet<Double> innerSet = new DiscreteFuzzySet<Double>(new DiscreteMembershipFunction(new HashMap<Object, Object>() {{ put(set.value(element), 1.0); }}));
			innerSet.elements = new CrispSet<Double>() {{ add((Double)set.value(element)); }};
			
			mappings.put(set.realValue(element), innerSet);
		}
    	 
    	Type2DiscreteFuzzySet<T> newSet = new Type2DiscreteFuzzySet<T>(new DiscreteMembershipFunction(mappings));
    	newSet.elements = set.elements;
    	newSet.column = set.column;
    	
    	return newSet;
	}
}

